home *** CD-ROM | disk | FTP | other *** search
-
- Great tool for a quick examination of a program. Only tool if you do not
- have access to the source. Useful for a sanity check of the appilcation.
- Is the programmer telling the truth about their code.
-
- o GLdebug can be used both to debug and to tune:
- - tells you what graphics calls are being issued
- - look for lots of mode changes, or unnecesssary mode settings
- - verify subpixel(1); glcompat(GLC_OLDPOLYGON, FALS);
- - check on:
- shademodel(FLAT/GOURAUD)
- infinite vs lights or LOCALVIEWER set in the Light Model
- two sided lighting
- mode changes:
- frequent calls to shademodel, zbuffer, blendfunction
- use of lmdef instead of lmcolor
- - check for duplicate data
- (often seen in normals and colors with flat-shading)
- - or unnecessary vertex bindings,
- such as uneeded per-vertex colors or normals for a flat shaded object.
- * must be single process to run gldebug
- * using ignore files will simplify gldebug output
-
-
- o What warning message are printed?
-
- Explanation of Options:
- -----------------------
- -h no history output.
- [run this option when you only want to see use the Stateviewer]
-
- -w no warning output.
-
- -e no error output.
-
- -f no fatal error output.
-
-
-
- -c do not run Controller.
-
- -s do not run Stateviewer.
- [run these options when you only want to see the output history, i.e. when
- you are looking for known bad habits which degrade performance. It may be
- useful to generate a history file in one pass then run the Stateviewer while
- examining the output.]
-
- -C generate C code in history file.
- [this is not very useful as the code never looks like the application.
- One may be able to reconstruct a bug without copying an unmanagably large
- size of application code. Also useful for producing a benchmark of the code
- in the application. This does not produce code which will compile.]
-
- -F flush output buffer to history file after each GL call.
-
- -p wait profile (output the number of times each GL function is
- called). wait is the number of GL calls wait between
- each profile write to file. Profile output goes to
- GLdebug.count.
-
- -i filename ignore the GL functions listed in filename when writing
- output. filename should contain GL function names listed
- one per line.
- [very useful for supressing commands which carry lots of data like texdef,
- defpattern, v3f, etc.]
-
- -o filename send history trace output to filename. Default is
- GLdebug.history.
-
- -O send history trace output to stdout. This overrides -o
- filename.
- [not very useful, history files are always big]
-
-
- o Useful alias: gldebug -i ~/gldignore -sF
- gldignore:
- -----------
- qread
- getmatrix
- defpattern
- texdef
-
- Taking a GLdebug Trace:
- -----------------------
- gldebug session to grab one frame:
- - start up gldebug
- - turn of output and breakpoints
- - set breakpoint at swapbuffers
- - go to interesting frame
- - turn on breakpoints
- > will stop at swapbuffers
- - turn on output
- - continue
- > will stop at swapbuffers, outputing one full scene to GLdebug.history
- - quit and look at output
-
- * note: grabbing one frame will show stuff set that frame but will
- not reflect modes that were set previously.
- therefore, it is best ot have a program that can come up in the
- desired location and with the desired modes and then grab
- the first 2 frames: 1 for initialization, one for
- continued drawing.
-
-
- EXAMPLE:
- --------
-
- > Vince,
- >
- > Here is a chunck of the output. Note that a number of different
- > techniques are used for drawing the models within the scene. So this
- > is only representative of a subset of the drawing (e.g. I don't even
- > know if any of the models in this section have textures turned on).
- >
-
- While working with Frank he thought that their code was finely tuned for
- VGX. He said something about a team of programmers working on the code
- for 10 man years. At first i had little confidence that we could improve his
- code, but i think we have found room for improvement.
-
- First as you both know if you move an app from the VGX to RE and see no
- improvement it probably means that you have a CPU bottleneck or something
- really stupid is being done in the graphics code. Unfortunately, we do not
- know what all of those "stupid" things are on RE yet.
- Also, in the demo that he is running there was no texture mapping.
- i am not surprise to learn that there was little improvement for non-texture
- mapped primitives. For standard phong lighted, Z-buffered, non-textured
- primitives the performance is about the same. The flat-shaded tmesh
- performance is exactly the same. The Gouraud shaded tmesh performance is
- about 10% higher on a RE.
- The biggest improvement comes with independent Gouraud shaded quads, about 33%.
- Turn on texturing and you get a big win.
-
- i helped Frank generate one frame of gldebug output and asked him to send
- me the file. A quick glance at the data reveals 3 sets of superfluous calls
- to the GL only 2 of which could impact performance. The improvements made here
- should result in improved performance on both VGX and RE since it will reduce
- the CPU bottleneck.
-
- 1) n3f
- 2) lmbind
- 3) misc.
-
- 1) The biggest problem is with duplicated normals. One trick to remember is that
- the hardware caches the normal and provides a copy with any
- subsequent vertexes that are sent without normals while lighting is enabled.
- If you look at the tmeshes you will notice 50 - 90+ % of the normal data
- is duplicated. Note i suppressed the gldebug output of v3f commands.
- If you look at the first FLAT shaded tmesh which has 12 vertexes you will
- see that 12 identical normals are being copied. That is 50% more data than
- necessary. Since lighting was enabled the same normal was also transformed
- for each copy. Furthermore, if multiple objects share the same normal it need
- only be sent once. This change may require rebuilding of the database.
-
- 2) It appears that every new lmbind call is preceded by a call to
- lmbind(MATERIAL, 0) which disables lighting. This is only necessary if they
- wish to draw an unlighted object. This is inefficeint toggling of modes. The
- RealityEngine is very sensitive to mode changes. Remove that lmbind.
-
- 3) There appear to be calls to things that are never used.
- e.g. getmatrix(), getpattern(), the query calls can be expensive because
- they are copying data back to the host or often have to go into feedback mode.
-
- Finally, it would be helpful to see some prof/pixie output from their program
- to verify this. If we are truely experiencing a CPU botteneck then you should
- see gl_i_v3f and gl_i_n3f listed at the very top of the pixie readings.
-
- good luck and i hope this helps,
- vince
-
- > getpattern();
- > getmatrix(OUT);
- > lmbind(MATERIAL, 0);
- > lmbind(MATERIAL, 5);
- > shademodel(GOURAUD);
- > bgntmesh();
- > n3f({1.000000, 0.000000, 0.000000});
- > n3f({1.000000, 0.000000, 0.000000});
- > n3f({0.500000, 0.797443, -0.337763});
- > n3f({0.500000, 0.797443, -0.337763});
- > n3f({-0.500000, 0.797443, -0.337763});
- > n3f({-0.500000, 0.797443, -0.337763});
- > n3f({-1.000000, 0.000000, 0.000000});
- > n3f({-1.000000, 0.000000, 0.000000});
- > n3f({-0.500000, -0.797443, 0.337763});
- > n3f({-0.500000, -0.797443, 0.337763});
- > n3f({0.500000, -0.797443, 0.337763});
- > n3f({0.500000, -0.797443, 0.337763});
- > n3f({1.000000, 0.000000, 0.000000});
- > n3f({1.000000, 0.000000, 0.000000});
- > endtmesh();
-
- > lmbind(MATERIAL, 0);
- > lmbind(MATERIAL, 6);
- > shademodel(FLAT);
- > bgntmesh();
- > n3f({-1.000000, 0.000000, 0.000000});
- > n3f({-1.000000, 0.000000, 0.000000});
- > swaptmesh();
- > n3f({-1.000000, 0.000000, 0.000000});
- > swaptmesh();
- > n3f({-1.000000, 0.000000, 0.000000});
- > swaptmesh();
- > n3f({-1.000000, 0.000000, 0.000000});
- > swaptmesh();
- > n3f({-1.000000, 0.000000, 0.000000});
- > swaptmesh();
- > n3f({-1.000000, 0.000000, 0.000000});
- > swaptmesh();
- > n3f({-1.000000, 0.000000, 0.000000});
- > swaptmesh();
- > n3f({-1.000000, 0.000000, 0.000000});
- > swaptmesh();
- > n3f({-1.000000, 0.000000, 0.000000});
- > swaptmesh();
- > n3f({-1.000000, 0.000000, 0.000000});
- > swaptmesh();
- > n3f({-1.000000, 0.000000, 0.000000});
- > endtmesh();
-
-